package jbeagle.core;

import java.util.Collection;

import jbeagle.config.ObjectFactory;

public class NumberListIndividualFactory<N extends Number> extends ListIndividualFactory<N> {

	protected N minInit, maxInit;
	private Class<N> runtimeType;
	
	public NumberListIndividualFactory(int minlen, int maxlen, Class<N> runtimeType) {
		super(minlen, maxlen);
		this.runtimeType = runtimeType;
		minInit = getGenericInstance(0);
		maxInit = getGenericInstance(1);
	}
	
	public NumberListIndividualFactory(int minlen, int maxlen, N mininit, N maxinit, Class<N> runtimeType) {
		super(minlen, maxlen);
		this.minInit = mininit;
		this.maxInit = maxinit;
		this.runtimeType = runtimeType;
	}

	public void setIndividualBoundaries(final N minval, final N maxval) {
        setConstraints( new Constraints<N>(){
			protected boolean violates(N val) {
                if(val.doubleValue() < minval.doubleValue() || val.doubleValue() > maxval.doubleValue())
                    return true;
                return false;
            }
        });
    }
	
	@Override
	protected void fillIndividual(ListIndividual<N> ind, int len) {
		double d = 0;
		for ( int i = 0; i < len; i++ ) {
			d = minInit.doubleValue() + Math.random() * (maxInit.doubleValue() - minInit.doubleValue());
			ind.add( getGenericInstance(d) );
		}
	}
	
	@Override
	protected void fillIndividual( ListIndividual<N> ind, Collection<String> values) {
		for ( String val : values )
			ind.add( getGenericInstance(val) );
	}
	
	protected N getGenericInstance(double val) {
		//all Numbers have a constructor that accepts a String value
		return (N) ObjectFactory.create(runtimeType.getName(), new String[]{String.class.getName()}, new String[]{"" + val});
	}
	
	protected N getGenericInstance(String val) {
		//all Numbers have a constructor that accepts a String value
		return (N) ObjectFactory.create(runtimeType.getName(), new String[]{String.class.getName()}, new String[]{val});
	}

}
